package com.bzyd.jpa.entity;

import com.alibaba.fastjson.JSON;
import lombok.Data;
import lombok.experimental.Accessors;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.UpdateTimestamp;
import org.hibernate.annotations.Where;

import javax.persistence.*;
import java.math.BigDecimal;
import java.util.Date;

/**
 * 订单表
 * Created by Xianyue Dang on 2021/8/27
 */
@Data
@Accessors(chain = true)
@Entity(name = "t_order")
//@Table(name = "xx_order") //上面两种写法都是映射实体类跟数据库表，但@Table优先级高于@Entity
@org.hibernate.annotations.Table(appliesTo = "t_order", comment = "订单表")//此注解可以增加表名注释
@SQLDelete(sql = "update t_order set is_delete = 1 where id = ?")//自定义逻辑删除SQL，注意当有@Version标识的字段时会报错，此时应该使用@Query定义删除SQL
@Where(clause = "is_delete = 0")//查询时会自动末尾加上此条件
public class Order {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", unique = true, nullable = false, columnDefinition = "bigint COMMENT '主键'")
    private Long id;

    /**
     * @GeneratedValue 注解及属性详解
     * JPA提供的四种标准用法为TABLE,SEQUENCE,IDENTITY,AUTO.
     * TABLE：使用一个特定的数据库表格来保存主键。
     * SEQUENCE：根据底层数据库的序列来生成主键，条件是数据库支持序列。
     * IDENTITY：主键由数据库自动生成（主要是自动增长型）
     * AUTO：主键由程序控制。
     */

    /**
     * @Column 注解及属性详解
     * name - 定义了被标注字段在数据库表中所对应字段的名称
     * unique - 表示该字段是否为唯一标识，默认为false
     * nullable - 表示该字段是否可以为null值，默认为true
     * insertable - 表示在使用“INSERT”脚本插入数据时，是否需要插入该字段的值，默认为true
     * updatable - 表示在使用“UPDATE”脚本插入数据时，是否需要更新该字段的值，默认为true（insertable和updatable属性一般多用于只读的属性，例如主键和外键等。这些字段的值通常是自动生成的。）
     * columnDefinition - 表示创建表时，该字段创建的SQL语句，一般用于通过Entity生成表定义时使用。（大多数情况，几乎不用，也就是说，如果DB中表已经建好，该属性没有必要使用。）
     * table - 表示当映射多个表时，指定表的表中的字段。默认值为主表的表名
     * length - 表示字段的长度，当字段的类型为varchar时，该属性才有效，默认为255个字符。
     * precision、scale - precision属性和scale属性表示精度，当字段类型为double时，precision表示数值的总长度，scale表示小数点所占的位数。
     */

    @Column(name = "order_no", unique = true, nullable = false, columnDefinition = "varchar(64) COMMENT '订单编号'")
    private String orderNo;

    @Column(name = "order_name", unique = false, nullable = true, columnDefinition = "varchar(100) COMMENT '订单名称'")
    private String orderName;

    @Column(name = "user_id", unique = false, nullable = false, columnDefinition = "bigint COMMENT '用户id'")
    private Long userId;

    @Column(name = "product_id", unique = false, nullable = false, columnDefinition = "bigint COMMENT '商品id'")
    private Long productId;

    @Column(name = "product_num", unique = false, nullable = false, columnDefinition = "int COMMENT '商品数量'")
    private Integer productNum;

    @Column(name = "amount", unique = false, nullable = false, columnDefinition = "decimal(32,2) COMMENT '订单金额'")
    private BigDecimal amount;

    @CreationTimestamp//插入时针对注解的属性对应的日期类型创建默认值。
    @Column(name = "create_time", unique = false, nullable = true, columnDefinition = "datetime COMMENT '创建时间'")
    private Date createTime;

    @UpdateTimestamp//更新时针对注解的属性对应的日期类型创建默认值。
    @Column(name = "update_time", unique = false, nullable = true, columnDefinition = "datetime COMMENT '更新时间'")
    private Date updateTime;

    //注意此设置会和@SQLDelete有冲突
//    @Version//此字段实现乐观锁功能，但是注意要用JPA的更新方法，如果是自己实现的方法则不生效
//    @Column(name = "version", unique = false, nullable = false, columnDefinition = "bigint default 0 COMMENT '版本号'")
//    private Long version;

    @Column(name = "is_delete", unique = false, nullable = false, columnDefinition = "int default 0 COMMENT '删除标示，0-正常，1-删除'")
    private Integer isDelete;

    //冗余保存用户名称字段
    @Transient//此属性为非持久化属性，不映射到数据库表中
    private String userName;

    @Override
    public String toString() {
        return JSON.toJSONString(this);
    }
}
